package neuralNetwork;


public class Neuron {
	
	private double[] weights; 
	private NeuralNetworkLayer nextLayer;
	private double input; 

	
	public Neuron(NeuralNetworkLayer nextLayer){
		if (nextLayer == null){
			weights = new double[1]; 
		}else {
			weights = new double[nextLayer.nofNeurons() + 1]; 
		}
		this.nextLayer = nextLayer; 
		input = 0; 
	}

	public int nofWeights() {
		return weights.length;
	}

	public double[] getWeights() {
		return weights;
	}

	public void setWeights(double[] weights) {
		this.weights = weights; 
	}
	
	public void updateInput(double update){
		input += update; 
	}
	
	public void fireUpdate(){
		if (nextLayer == null){
			return; 
		}
		double output = OutputFunctions.logisticFunction(input, weights[nofWeights()-1]);
		for (int i = 0; i < weights.length - 1; i++){
			nextLayer.get(i).updateInput(output * weights[i]);
		}
		input = 0; 
	}
	
	public String toString(){
		String theString = ""; 
		for (int i = 0; i < weights.length; i++) {
			theString += Double.toString(weights[i]) + " ";
		}
		return theString; 
	}
	
	public static class OutputFunctions{
		
		public static double logisticFunction(double input, double threshold){
			double slope = 0.05; 
			double output = 1/(1+Math.pow(Math.E, (-input + threshold)/slope));  
			return output; 
		}
		
	}

	public void setInput(double inputs) {
		this.input = inputs; 
	}
	
	public double returnOutput(){
		double output = OutputFunctions.logisticFunction(input, weights[nofWeights()-1]);
		input = 0; 
		return output;
	}
	
	

}
